using System;
using GammaJul.ReSharper.GammaXaml.Highlightings.Xaml;
using GammaJul.ReSharper.GammaXaml.Psi.Xaml;
using JetBrains.Annotations;
using JetBrains.DocumentModel;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Daemon;
using JetBrains.ReSharper.Daemon.Impl;
using JetBrains.ReSharper.Psi.Xml.Tree;
using JetBrains.Util;

[assembly: RegisterConfigurableSeverity(
	GridDefinitionValueOutOfRangeHighlighting.SeverityId,
	null,
	HighlightingGroupIds.CodeSmell,
	GridDefinitionValueOutOfRangeHighlighting.Description,
	GridDefinitionValueOutOfRangeHighlighting.Description,
	Severity.WARNING,
	false)]

namespace GammaJul.ReSharper.GammaXaml.Highlightings.Xaml {

	/// <summary>
	/// An highlighting that indicates that a row or column definition setter value is out of range.
	/// </summary>
	[ConfigurableSeverityHighlighting(SeverityId, XamlProjectFileType.Name, OverlapResolve = OverlapResolveKind.WARNING)]
	public class GridDefinitionValueOutOfRangeHighlighting : IHighlightingWithRange {
		internal const string SeverityId = "Xaml.GridDefinitionValueOutOfRange";
		internal const string Description = "Value is outside of the range of the Row/ColumnDefinitions.";

		private readonly IXmlToken _valueToken;
		private readonly ReadOnlyList<string> _gridDefinitionSizes;
		private readonly GridDefinitionType _definitionType;

		/// <summary>
		/// Gets the token having an out of range value.
		/// </summary>
		[NotNull]
		public IXmlToken ValueToken {
			get { return _valueToken; }
		}

		/// <summary>
		/// Gets information about the grid definition sizes.
		/// </summary>
		[NotNull]
		public ReadOnlyList<string> GridDefinitionSizes {
			get { return _gridDefinitionSizes; }
		}

		/// <summary>
		/// Returns the type of grid definition.
		/// </summary>
		public GridDefinitionType DefinitionType {
			get { return _definitionType; }
		}

		public string ToolTip {
			get { return Description; }
		}

		public string ErrorStripeToolTip {
			get { return Description; }
		}

		public int NavigationOffsetPatch {
			get { return 0; }
		}

		public bool IsValid() {
			return _valueToken.IsValid();
		}

		public DocumentRange CalculateRange() {
			return _valueToken.GetHighlightingRange();
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="GridDefinitionValueOutOfRangeHighlighting"/> class.
		/// </summary>
		/// <param name="valueToken">The token having an out of range value.</param>
		/// <param name="gridDefinitionSizes">Information about the grid definition sizes.</param>
		/// <param name="definitionType">The type of grid definition.</param>
		public GridDefinitionValueOutOfRangeHighlighting([NotNull] IXmlToken valueToken, [NotNull] ReadOnlyList<string> gridDefinitionSizes, GridDefinitionType definitionType) {
			if (valueToken == null)
				throw new ArgumentNullException("valueToken");
			if (gridDefinitionSizes == null)
				throw new ArgumentNullException("gridDefinitionSizes");

			_valueToken = valueToken;
			_gridDefinitionSizes = gridDefinitionSizes;
			_definitionType = definitionType;
		}
	}

}
